home *** CD-ROM | disk | FTP | other *** search
- /*
- ### Solving a linear equation, A x = b, ###
- -----------------------------------------------------------------------
-
- LINSOL.C Kim 9/1988
-
-
- Algorithm: Guassian elimination with partial pivoting
-
-
- Input: A = n x n matrix, b = n dim vector
- Output: x = n dim solution
- Return: -1 in case of error, 0 otherwise
-
- -----------------------------------------------------------------------
- Bug: Need to specify Maximum matrix dimension.
- -----------------------------------------------------------------------
- Reference: P136 John R. Rice
- ----------------------------------------------------------------------
- */
- #include <math.h>
- int
- linsol(x,a,b,n)
- int n;
- double *x,**a,*b;
- {
- int stop,i,j,k,imax;
- double det;
- double r,m,sum,amax,atmp,btmp,fabs();
- static double buffer = { 1.5e-16 };
-
- switch(n){
- case 1:
- if(a[0][0]==0)
- return(-1);
- else
- x[0] = 1./ a[0][0];
- break;
- case 2:
- det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
- if(det == 0)
- return(-1);
- x[0] = (a[1][1] * b[0] - a[0][1] * b[1])/det;
- x[1] = (a[0][0] * b[1] - a[1][0] * b[0])/det;
- break;
- default:
- for(k=0;k<=n-2;k++){
- imax=k;
- amax = fabs(a[k][k]);
- for(i=k;i<=n-1;i++){
- if(fabs(a[i][k])>= amax) {
- imax=i;
- amax=a[i][k];
- }
- }
- if(fabs(a[imax][k]) <= buffer)
- break;
- for(j=0;j<=n-1;j++){
- atmp = a[k][j];
- a[k][j] = a[imax][j];
- a[imax][j]=atmp;
- }
- btmp = b[k];
- b[k] = b[imax];
- b[imax] = btmp;
- for(i=k+1;i<=n-1;i++){
- m = a[i][k] /= a[k][k];
- for(j=k+1;j<=n-1;j++){
- a[i][j] -= m * a[k][j];
- }
- b[i] -= m * b[k];
- }
- }
- for(i=n-1;i>=0;i--) {
- sum=0;
- for(j=i+1;j<=n-1;j++)
- sum += a[i][j] * x[j];
- r = b[i] - sum;
- if(fabs(a[i][i]) > buffer) {
- x[i] = r/a[i][i];
- }
- else if(fabs(r) <= buffer) {
- x[i] = 0;
- printf("A is singular, consistent system\n");
- stop = 1;
- return(stop);
- }
- else {
- printf("A is singular, inconsistent system\n");
- stop = 1;
- return(stop);
- }
- }
- break;
- }
- return(stop);
- }
-